{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "# SVD+LDA 分析方法"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "选取了80个特征\n",
      "(200, 6400)\n"
     ]
    }
   ],
   "source": [
    "# 人脸识别是一个分类问题\n",
    "# svc 支持向量解决分类问题\n",
    "import cv2\n",
    "import numpy as np\n",
    "import os\n",
    "\n",
    "data_path = r\"att_faces\"\n",
    "\n",
    "# 使用50个特征值作为该图像的特征信息\n",
    "K = 80\n",
    "print(\"选取了{}个特征\".format(K))\n",
    "\n",
    "\n",
    "def read_image():\n",
    "    \"\"\"\n",
    "    加载图片信息\n",
    "    :return:\n",
    "    \"\"\"\n",
    "    A = np.zeros((112, 92))\n",
    "    image = []\n",
    "    root_path = os.listdir(data_path)\n",
    "\n",
    "    for d in root_path:\n",
    "        s_path = os.path.join(data_path, d)\n",
    "        for idx, image_path in enumerate(os.listdir(s_path)):\n",
    "            # 因为是二维图,所以是二维的 [112,92]\n",
    "            img = cv2.imread(os.path.join(s_path, image_path), cv2.IMREAD_GRAYSCALE)\n",
    "            # 把[112 92]的图片信息转变成 一维数组\n",
    "            image.append(img)\n",
    "            A += img\n",
    "    return np.array(image), A / 400\n",
    "\n",
    "\n",
    "def train():\n",
    "    \"\"\"\n",
    "    进行训练,训练的目的就是把40 张图片的所有 特征值提取出来，放进sigma_data\n",
    "    :return:\n",
    "    \"\"\"\n",
    "    global sigma_data\n",
    "    u, sigma, v = np.linalg.svd(A)\n",
    "    for image in train_data:\n",
    "        # 数据进行展示\n",
    "        temp = np.dot(np.dot(u.T, image), v)[0:K, 0:K].flatten()\n",
    "\n",
    "        sigma_data.append(temp)\n",
    "\n",
    "    print(\"训练结束\")\n",
    "\n",
    "\n",
    "def test():\n",
    "    \"\"\"\n",
    "    用提前准备好的图片 做最近邻算法的比较,和谁的最近邻 小\n",
    "\n",
    "    :return:\n",
    "    \"\"\"\n",
    "    # 分类正确的个数\n",
    "    acc = 0\n",
    "    for idx, image in enumerate(test_data):\n",
    "        u, sigma, v = np.linalg.svd(image)\n",
    "        # 对sigma 从小到大排序\n",
    "        sigma = np.sort(sigma)\n",
    "        # 选取特征值K个最大特征值作为Sm_i的特征值\n",
    "        sigma = sigma[-K:]\n",
    "        m = get_index(sigma)\n",
    "        raw = int(idx / 5) + 1\n",
    "        predict = int(m / 5) + 1\n",
    "        if raw == predict:\n",
    "            acc += 1\n",
    "            print(\"这张图预测为{},预测正确\".format(predict, raw))\n",
    "        else:\n",
    "            print(\"这张图预测为{},预测错误,本来是{}\".format(predict, raw))\n",
    "\n",
    "    print(\"最终准确率{}%,--[{}/{}]\".format(100 * acc / len(test_data), acc, len(test_data)))\n",
    "    # 使用\n",
    "\n",
    "\n",
    "def get_index(sigma):\n",
    "    \"\"\"\n",
    "    求出最小近邻的 所在是索引值\n",
    "    :param sigma: 测试图像的前 K 个最大特征值\n",
    "    :return:\n",
    "    \"\"\"\n",
    "    index = []\n",
    "    for i in sigma_data:\n",
    "        # 最小近邻，其实就是求第二范数\n",
    "        index.append(np.linalg.norm(i - sigma))\n",
    "    return np.argmin(index)\n",
    "\n",
    "\n",
    "sigma_data = []\n",
    "\n",
    "image, A = read_image()\n",
    "# (400, 10304)，[112,92]\n",
    "\n",
    "u, eigval, v = np.linalg.svd(A)\n",
    "\n",
    "# A表示所有训练样本的均值\n",
    "# 对数据集进行拆分\n",
    "train_data = image[0::2]\n",
    "test_data = image[1::2]\n",
    "\n",
    "t = []\n",
    "# 把所有的训练样本，投影积空间中\n",
    "for pic in train_data:\n",
    "    d = np.dot(u.T.dot(pic), v)\n",
    "    # 提取左上角k*k区域的数据,并拉成一维向量x_j\n",
    "    t.append(d[0:K, 0:K].flatten())\n",
    "\n",
    "t=np.array(t)\n",
    "print(t.shape)\n",
    "# for value in t:\n",
    "\n",
    "\n",
    "\n",
    "# 计算类间散度矩阵Sb\n"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}